#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) ://类的构造函数
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //初始化游戏数组为0
    for(int i=0;i<4;i++){
        for(int j=0;j<4;j++){
            s[i][j]=0;
        }
    }

    button=new QPushButton("开始游戏",this);
    button->setGeometry(280,60,200,50);//放置开始游戏按钮，前两个为按钮的坐标位置，后两个为按钮的长宽大小

    //随机函数
    qsrand(uint(QTime(0,0,0).secsTo(QTime::currentTime())));

    //槽与信号
    connect(button,SIGNAL(clicked()),this,SLOT(slotStart()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::paintEvent(QPaintEvent *)//填充颜色
{
    QPainter p(this);
    p.setBrush(Qt::blue);//setBrush填充几何图形的调色板
    p.setFont((QFont("微软雅黑",20,700,false)));//设置字体

    QString strscore;
    p.drawText(QPoint(20,60),"分数："+QString::number(score));//实时显示分数

    //格子的实现
    QColor digitBkg[11] = {QColor::fromRgb(0xEE, 0xE5, 0xDB), QColor::fromRgb(0xEC, 0xE0, 0xC8),
                                QColor::fromRgb(0xF2, 0xAF, 0x78), QColor::fromRgb(0xEE, 0x8A, 0x54),
                                QColor::fromRgb(0xFE, 0x76, 0x5E), QColor::fromRgb(0xE7, 0x58, 0xC),
                                QColor::fromRgb(0xFF, 0x66, 0x66), QColor::fromRgb(0xF1, 0xCF, 0x48),
                                QColor::fromRgb(0xCC, 0x33, 0x33), QColor::fromRgb(0xE3, 0xB9, 0x11),
                                QColor::fromRgb(0xFF, 0x00, 0x00)};
    for(int i=0;i<4;i++){
        for(int j=0;j<4;j++){
            p.setPen(Qt::transparent);//transparent是透明，setpen是设置边界
            if(s[i][j]==0){
                p.setBrush(Qt::gray);//0的时候格子填充为灰色
                p.drawRect(i*100+55,j*100+120,90,90);//放置格子，前两个为格子的坐标位置，后两个为格子的长宽大小
            }
            else if (s[i][j]==2) {
                //p.setBrush(Qt::red);
                // 设置画刷颜色为 RGB分量为171 165 141的颜色
                //QBrush brush;//(QColor::fromRgb(141, 121, 81));
                //brush.setColor(QColor::fromRgb(0xFF, 0x66, 0x66));
                // 应用这个画刷
                p.setBrush(digitBkg[0]);
                p.drawRect(i*100+55,j*100+120,90,90);
                p.setPen(Qt::black);
                p.setFont(QFont("微软雅黑",20,700,false));//控制字体和字颜色
                p.drawText(QRectF(i*100+55,j*100+120,90,90)/*字符位置*/,QString::number(2)/*将2转化为字符串并填充*/,QTextOption(Qt::AlignCenter)/*填充的字符串居中对齐*/);//在格子中绘制字符串


            }
            else if (s[i][j]==4) {
                p.setBrush(digitBkg[1]);
                p.drawRect(i*100+55,j*100+120,90,90);
                p.setPen(Qt::black);
                p.setFont(QFont("微软雅黑",20,700,false));//控制字体和字颜色
                p.drawText(QRectF(i*100+55,j*100+120,90,90)/*字符位置*/,QString::number(4)/*将4转化为字符串并填充*/,QTextOption(Qt::AlignCenter)/*填充的字符串居中对齐*/);//在格子中绘制字符串


            }
            else if (s[i][j]==8) {
                p.setBrush(digitBkg[2]);
                p.drawRect(i*100+55,j*100+120,90,90);
                p.setPen(Qt::black);
                p.setFont(QFont("微软雅黑",20,700,false));//控制字体和字颜色
                p.drawText(QRectF(i*100+55,j*100+120,90,90)/*字符位置*/,QString::number(8)/*将8转化为字符串并填充*/,QTextOption(Qt::AlignCenter)/*填充的字符串居中对齐*/);//在格子中绘制字符串


            }
            else if (s[i][j]==16) {
                p.setBrush(digitBkg[3]);
                p.drawRect(i*100+55,j*100+120,90,90);
                p.setPen(Qt::black);
                p.setFont(QFont("微软雅黑",20,700,false));//控制字体和字颜色
                p.drawText(QRectF(i*100+55,j*100+120,90,90)/*字符位置*/,QString::number(16)/*将16转化为字符串并填充*/,QTextOption(Qt::AlignCenter)/*填充的字符串居中对齐*/);//在格子中绘制字符串


            }
            else if (s[i][j]==32) {
                p.setBrush(digitBkg[4]);
                p.drawRect(i*100+55,j*100+120,90,90);
                p.setPen(Qt::black);
                p.setFont(QFont("微软雅黑",20,700,false));//控制字体和字颜色
                p.drawText(QRectF(i*100+55,j*100+120,90,90)/*字符位置*/,QString::number(32)/*将32转化为字符串并填充*/,QTextOption(Qt::AlignCenter)/*填充的字符串居中对齐*/);//在格子中绘制字符串


            }
            else if (s[i][j]==64) {
                p.setBrush(digitBkg[5]);
                p.drawRect(i*100+55,j*100+120,90,90);
                p.setPen(Qt::black);
                p.setFont(QFont("微软雅黑",20,700,false));//控制字体和字颜色
                p.drawText(QRectF(i*100+55,j*100+120,90,90)/*字符位置*/,QString::number(64)/*将64转化为字符串并填充*/,QTextOption(Qt::AlignCenter)/*填充的字符串居中对齐*/);//在格子中绘制字符串


            }
            else if (s[i][j]==128) {
                p.setBrush(digitBkg[6]);
                p.drawRect(i*100+55,j*100+120,90,90);
                p.setPen(Qt::black);
                p.setFont(QFont("微软雅黑",20,700,false));//控制字体和字颜色
                p.drawText(QRectF(i*100+55,j*100+120,90,90)/*字符位置*/,QString::number(128)/*将128转化为字符串并填充*/,QTextOption(Qt::AlignCenter)/*填充的字符串居中对齐*/);//在格子中绘制字符串


            }
            else if (s[i][j]==256) {
                p.setBrush(digitBkg[7]);
                p.drawRect(i*100+55,j*100+120,90,90);
                p.setPen(Qt::black);
                p.setFont(QFont("微软雅黑",20,700,false));//控制字体和字颜色
                p.drawText(QRectF(i*100+55,j*100+120,90,90)/*字符位置*/,QString::number(256)/*将256转化为字符串并填充*/,QTextOption(Qt::AlignCenter)/*填充的字符串居中对齐*/);//在格子中绘制字符串


            }
            else if (s[i][j]==512) {
                p.setBrush(digitBkg[8]);
                p.drawRect(i*100+55,j*100+120,90,90);
                p.setPen(Qt::black);
                p.setFont(QFont("微软雅黑",20,700,false));//控制字体和字颜色
                p.drawText(QRectF(i*100+55,j*100+120,90,90)/*字符位置*/,QString::number(512)/*将512转化为字符串并填充*/,QTextOption(Qt::AlignCenter)/*填充的字符串居中对齐*/);//在格子中绘制字符串


            }
            else if (s[i][j]==1024) {
                p.setBrush(digitBkg[9]);
                p.drawRect(i*100+55,j*100+120,90,90);
                p.setPen(Qt::black);
                p.setFont(QFont("微软雅黑",20,700,false));//控制字体和字颜色
                p.drawText(QRectF(i*100+55,j*100+120,90,90)/*字符位置*/,QString::number(1024)/*将1024转化为字符串并填充*/,QTextOption(Qt::AlignCenter)/*填充的字符串居中对齐*/);//在格子中绘制字符串


            }
            else if (s[i][j]==2048) {
                p.setBrush(digitBkg[10]);
                p.drawRect(i*100+55,j*100+120,90,90);
                p.setPen(Qt::black);
                p.setFont(QFont("微软雅黑",20,700,false));//控制字体和字颜色
                p.drawText(QRectF(i*100+55,j*100+120,90,90)/*字符位置*/,QString::number(2048)/*将2048转化为字符串并填充*/,QTextOption(Qt::AlignCenter)/*填充的字符串居中对齐*/);//在格子中绘制字符串


            }
            else {
                p.setBrush(digitBkg[11]);
                p.drawRect(i*100+55,j*100+120,90,90);
                p.setPen(Qt::black);
                p.setFont(QFont("微软雅黑",20,700,false));//控制字体和字颜色
                p.drawText(QRectF(i*100+55,j*100+120,90,90)/*字符位置*/,QString::number(s[i][j])/*将s[i][j]转化为字符串并填充*/,QTextOption(Qt::AlignCenter)/*填充的字符串居中对齐*/);//在格子中绘制字符串


            }
        }
    }


}
void MainWindow::slotStart()//点击开始游戏后初始化（同时实现弹窗显示游戏规则）
{
    //游戏开始或重新开始的函数
    QMessageBox::about(this,"游戏规则","WASD控制方块上下左右移动");
    score=0;//分数清零
    for(int i=0;i<4;i++){
        for(int j=0;j<4;j++){
            s[i][j]=0;//数组清零
        }
    }

    button->setText("重新开始");

    int randi=qrand()%4;//0123随机生成行数
    int randj=qrand()%4;//0123随机生成列数
    s[randi][randj]=2;//生成一个随机位置的2
    state=true;
    update();

}
void MainWindow::PressUp()
{
    //移动过程的实现
    for(int i=0;i<4;i++){
        for(int j=1;j<4;j++){
            if(s[i][j]==0){
                continue;
            }
            for(int p=0;p<j;p++){
                //查找上面是否有空格可以移动
                if(s[i][p]==0){
                    s[i][p]=s[i][j];
                    s[i][j]=0;
                    break;
                }
            }
        }
    }
    //相加过程的实现
    for(int i=0;i<4;i++){
        for(int j=0;j<3;j++){
            if(s[i][j]==s[i][j+1]){
                s[i][j]*=2;
                s[i][j+1]=0;
                score+=s[i][j];
                for(int p=j+1;p<3;p++){
                    s[i][p]=s[i][p+1];
                    s[i][p+1]=0;
                }

            }
        }
    }
}

void MainWindow::PressDown()
{

    //移动过程的实现
    for(int i=0;i<4;i++){
        for(int j=2;j>=0;j--){
            if(s[i][j]==0){
                continue;
            }
            for(int p=3;p>j;p--){
                //查找下面是否有空格可以移动
                if(s[i][p]==0){
                    s[i][p]=s[i][j];
                    s[i][j]=0;
                    break;
                }
            }
        }
    }
    //相加过程的实现
    for(int i=0;i<4;i++){
        for(int j=3;j>0;j--){
            if(s[i][j]==s[i][j-1]){
                s[i][j]*=2;
                s[i][j-1]=0;
                score+=s[i][j];
                for(int p=j-1;p>0;p--){
                    s[i][p]=s[i][p-1];
                    s[i][p-1]=0;
                }

            }
        }
    }
}

void MainWindow::PressLeft()
{

    //移动过程的实现
    for(int j=0;j<4;j++){
        for(int i=1;i<4;i++){
            if(s[i][j]==0){
                continue;
            }
            for(int p=0;p<i;p++){
                //查找左面是否有空格可以移动
                if(s[p][j]==0){
                    s[p][j]=s[i][j];
                    s[i][j]=0;
                    break;
                }
            }
        }
    }
    //相加过程的实现
    for(int j=0;j<4;j++){
        for(int i=0;i<3;i++){
            if(s[i][j]==s[i+1][j]){
                s[i][j]*=2;;
                s[i+1][j]=0;
                score+=s[i][j];
                for(int p=i+1;p<3;p++){
                    s[p][j]=s[p+1][j];
                    s[p+1][j]=0;
                }

            }
        }
    }
}

void MainWindow::PressRight()
{

    //移动过程的实现
    for(int j=0;j<4;j++){
        for(int i=2;i>=0;i--){
            if(s[i][j]==0){
                continue;
            }
            for(int p=3;p>i;p--){
                //查找下面是否有空格可以移动
                if(s[p][j]==0){
                    s[p][j]=s[i][j];
                    s[i][j]=0;
                    break;
                }
            }
        }
    }
    //相加过程的实现
    for(int j=0;j<4;j++){
        for(int i=3;i>0;i--){
            if(s[i][j]==s[i-1][j]){
                s[i][j]*=2;
                s[i-1][j]=0;
                score+=s[i][j];
                for(int p=i-1;p>0;p--){
                    s[p][j]=s[p-1][j];
                    s[p-1][j]=0;
                }

            }
        }
    }
}
void MainWindow::myRand()
{
    //先找出空的格子
    int i=0;
    int j=0;

    //找到格子
    struct Ns n[16];
    int ni=0;
    for(i=0;i<4;i++){
        for(j=0;j<4;j++){
            if(s[i][j]==0){
                n[ni].i=i;
                n[ni].j=j;
                ni++;
            }
        }
    }

    //判断游戏是否结束
    if(ni==0){
        for(i=0;i<4;i++){
            for(j=0;j<3;j++){
                if(s[i][j]==s[i][j+1]){
                    return ;
                }
            }
        }
        for(j=0;j<4;j++){
            for(i=0;i<4;i++){
                if(s[i][j]==s[i+1][j]){
                    return ;
                }
            }
        }
        QMessageBox::about(this,"游戏结束","分数为："+QString::number(score)+"");
        return ;
    }
    //随机在空格子里生成一个2
    int rand=qrand()%ni;
    s[n[rand].i][n[rand].j]=2;
}

void MainWindow::keyPressEvent(QKeyEvent *event)//槽函数实现控制
{
    if(!state){//控制游戏结束
        return ;
    }
    switch(event->key()){//读取键盘
    case Qt::Key_W:
        PressUp();
        break;
    case Qt::Key_S:
        PressDown();
        break;
    case Qt::Key_A:
        PressLeft();
        break;
    case Qt::Key_D:
        PressRight();
        break;
    default:
        return ;//忽略其他按键的操作
    }
    //随机函数myRand();
    myRand();//每次操作之后随机位置生成一个2
    update();//强制界面刷新，界面重新绘制一遍paintEvent();
}
